package com.drakulo.games.ais.core;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Stack;

import org.newdawn.slick.GameContainer;
import org.newdawn.slick.state.StateBasedGame;
import org.newdawn.slick.tiled.TiledMap;

import com.drakulo.games.ais.core.delayed.HexagonMapAction;
import com.drakulo.games.ais.core.io.TechnologyIO;
import com.drakulo.games.ais.core.tech.Technology;

/**
 * <h1>The current game data</h1>
 * <p>
 * This class is a static wrapper containing current game resources and
 * informations. No logic is done there, only variable storing!
 * </p>
 * 
 * @author Drakulo
 * 
 */
public final class GameData {
	/** The player's colonies */
	private static List<Colony> colonies;
	/** The selected colony */
	private static Colony selectedColony;
	/** All technologies, owned or to search */
	private static Map<String, Technology> technologies;
	/** The last viewed technology in the research state */
	private static Technology lastViewedTechnology;
	/** Exploration actions */
	private static List<HexagonMapAction> hexagonMapActions;
	/** The game (used for state transitions) */
	private static transient StateBasedGame game;
	/** The game container (used for asynchronous actions) */
	private static transient GameContainer gameContainer;
	/**
	 * For thread safety, colonies created are added in this stack and handled
	 * by the game engine
	 */
	private static Stack<Colony> colonyPool;

	/** Private constructor to force static access */
	private GameData() {
		// Nothing there
	}

	/**
	 * This method initializes the private static membres
	 */
	public static void initialize() {
		colonies = new ArrayList<Colony>();
		hexagonMapActions = new ArrayList<HexagonMapAction>();
		colonyPool = new Stack<Colony>();
		setTechnologies(TechnologyIO.loadTechnologies());
	}

	public static TiledMap getCurrentMap() {
		return selectedColony.getMap();
	}

	/**
	 * @return the current map's width
	 */
	public static int getCurrentMapWidth() {
		return getCurrentMap().getWidth() * Settings.TILE_SIZE;
	}

	/**
	 * @return the current map's height
	 */
	public static int getCurrentMapHeight() {
		return getCurrentMap().getHeight() * Settings.TILE_SIZE;
	}

	public static void setTechnologies(Map<String, Technology> technologies) {
		GameData.technologies = technologies;
	}

	public static List<Technology> getTechnologies() {
		List<Technology> l = new ArrayList<Technology>();
		l.addAll(technologies.values());
		return l;
	}

	public static Map<String, Technology> getTechnologyMap() {
		return technologies;
	}

	public static Technology getLastViewedTechnology() {
		return lastViewedTechnology;
	}

	public static void setLastViewedTechnology(Technology lastViewedTechnology) {
		GameData.lastViewedTechnology = lastViewedTechnology;
	}

	public static StateBasedGame getGame() {
		return game;
	}

	public static void setGame(StateBasedGame game) {
		GameData.game = game;
	}

	public static void setGameContainer(GameContainer gameContainer) {
		GameData.gameContainer = gameContainer;
	}

	public static GameContainer getGameContainer() {
		return gameContainer;
	}

	public static List<Colony> getColonies() {
		return colonies;
	}

	public static void setColonies(List<Colony> colonies) {
		GameData.colonies = colonies;
	}

	public static Colony getSelectedColony() {
		return selectedColony;
	}

	public static void setSelectedColony(Colony currentColony) {
		GameData.selectedColony = currentColony;
	}

	public static void addColony(Colony c) {
		GameData.colonies.add(c);
	}

	public static void addHexagonMapAction(HexagonMapAction action) {
		GameData.hexagonMapActions.add(action);
	}

	public static List<HexagonMapAction> getHexagonMapActions() {
		return GameData.hexagonMapActions;
	}

	public static void putInPool(Colony c) {
		GameData.colonyPool.push(c);
	}

	public static Colony popColonyFromPool() {
		if (GameData.colonyPool.isEmpty()) {
			return null;
		}
		return GameData.colonyPool.pop();
	}
}
